package cn.edu.hbvtc.qms.service.impl;

import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Set;

import org.springframework.context.support.MessageSourceAccessor;
import org.springframework.dao.DataAccessException;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.SpringSecurityMessageSource;
import org.springframework.security.core.authority.GrantedAuthorityImpl;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.transaction.annotation.Transactional;

import cn.edu.hbvtc.qms.domain.Clazz;
import cn.edu.hbvtc.qms.domain.Course;
import cn.edu.hbvtc.qms.domain.Department;
import cn.edu.hbvtc.qms.domain.Major;
import cn.edu.hbvtc.qms.domain.Role;
import cn.edu.hbvtc.qms.domain.Student;
import cn.edu.hbvtc.qms.domain.Term;
import cn.edu.hbvtc.qms.domain.Teacher;
import cn.edu.hbvtc.qms.domain.User;
import cn.edu.hbvtc.qms.persist.IClazzDao;
import cn.edu.hbvtc.qms.persist.ICourseDao;
import cn.edu.hbvtc.qms.persist.IDepartmentDao;
import cn.edu.hbvtc.qms.persist.IMajorDao;
import cn.edu.hbvtc.qms.persist.IRoleDao;
import cn.edu.hbvtc.qms.persist.IStudentDao;
import cn.edu.hbvtc.qms.persist.ITermDao;
import cn.edu.hbvtc.qms.persist.ITeacherDao;
import cn.edu.hbvtc.qms.persist.IUserDao;
import cn.edu.hbvtc.qms.service.IManagementService;

@Transactional
public class ManagementService implements IManagementService {

	private IRoleDao roleDao = null;
	private IUserDao userDao = null;
	private IDepartmentDao deptDao = null;
	private IClazzDao clazzDao = null;
	private ICourseDao courseDao = null;

	private IMajorDao majorDao = null;
	private ITermDao termDao = null;
	private ITeacherDao teacherDao = null;
	private IStudentDao studentDao = null;


	protected MessageSourceAccessor messages = SpringSecurityMessageSource
			.getAccessor();

	public IRoleDao getRoleDao() {
		return roleDao;
	}

	public void setRoleDao(IRoleDao roleDao) {
		this.roleDao = roleDao;
	}

	public IUserDao getUserDao() {
		return userDao;
	}

	public void setUserDao(IUserDao userDao) {
		this.userDao = userDao;
	}

	public IDepartmentDao getDeptDao() {
		return deptDao;
	}

	public void setDeptDao(IDepartmentDao deptDao) {
		this.deptDao = deptDao;
	}

	public void setMajorDao(IMajorDao majorDao) {
		this.majorDao = majorDao;
	}

	public IMajorDao getMajorDao() {
		return majorDao;
	}

	public void setTeacherDao(ITeacherDao teacherDao) {
		this.teacherDao = teacherDao;
	}

	public IClazzDao getClazzDao() {
		return clazzDao;
	}

	public ITeacherDao getTeacherDao() {
		return teacherDao;
	}

	public void setClazzDao(IClazzDao clazzDao) {
		this.clazzDao = clazzDao;
	}

	public ICourseDao getCourseDao() {
		return courseDao;
	}

	public void setCourseDao(ICourseDao courseDao) {
		this.courseDao = courseDao;
	}

	public ITermDao getTermDao() {
		return termDao;
	}

	public void setTermDao(ITermDao termDao) {
		this.termDao = termDao;
	}

	public IStudentDao getStudentDao() {
		return studentDao;
	}

	public void setStudentDao(IStudentDao studentDao) {
		this.studentDao = studentDao;
	}

	@Override
	public void deleteRoleById(int id) {
		Role role = roleDao.findById(id);
		roleDao.delete(role);
	}

	@Override
	public void deleteUserById(int id) {
		User user = userDao.findById(id);
		userDao.delete(user);
	}

	@Override
	public Role findRoleById(int id) {
		return roleDao.findById(id);
	}

	@Override
	public List<Role> findRoles() {
		return roleDao.findAll();
	}

	@Override
	public User findUserById(int id) {
		return userDao.findById(id);
	}

	@Override
	public User findUserByUsername(String username) {
		return userDao.findUserByUserName(username);
	}

	@Override
	public List<User> findUsers() {
		return userDao.findAll();
	}

	@Override
	public List<User> findUsersByRoleName(String roleName) {
		return roleDao.findUsersByRoleName(roleName);
	}

	@Override
	public void saveRole(Role role) {
		roleDao.save(role);
	}

	@Override
	public void saveUser(User user) {
		userDao.save(user);
	}

	@Override
	public void updateRole(Role role) {
		roleDao.update(role);
	}

	@Override
	public void updateUser(User user) {
		userDao.update(user);
	}

	@Override
	public UserDetails loadUserByUsername(String username)
			throws UsernameNotFoundException, DataAccessException {
		User user = userDao.findUserByUserName(username);

		if (user == null) {
			throw new UsernameNotFoundException(messages.getMessage(
					"JdbcDaoImpl.notFound", new Object[] { username },
					"Username {0} not found"), username);
		}

		Set<Role> roles = user.getRoles();
		if (roles == null || roles.size() == 0) {
			throw new UsernameNotFoundException(messages.getMessage(
					"JdbcDaoImpl.notAuthority", new Object[] { username },
					"User {0} has no GrantedAuthority"), username);
		}

		Set<GrantedAuthority> authorities = new HashSet<GrantedAuthority>();
		for (Iterator iter = roles.iterator(); iter.hasNext();) {
			Role role = (Role) iter.next();
			GrantedAuthority authority = new GrantedAuthorityImpl("ROLE_"
					+ role.getName());
			authorities.add(authority);
		}

		return new org.springframework.security.core.userdetails.User(user
				.getUsername(), user.getPassword(), true, true, true, true,
				authorities);
	}

	@Override
	public void deleteDepartmentById(int id) {
		Department dept = deptDao.findById(id);
		deptDao.delete(dept);
	}

	@Override
	public Department findDepartmentById(int id) {
		return deptDao.findById(id);
	}

	@Override
	public Department findDepartmentByDeptId(String deptId) {
		return deptDao.findDepartmentByDeptId(deptId);
	}

	@Override
	public List<Department> findDepartments() {
		return deptDao.findAll();
	}

	@Override
	public void saveDepartment(Department department) {
		deptDao.save(department);
	}

	@Override
	public void updateDepartment(Department department) {
		deptDao.update(department);
	}

	@Override
	public void deleteMajorById(int id) {
		Major major = majorDao.findById(id);
		majorDao.delete(major);
	}

	@Override
	public List<Major> findMajors() {
		return majorDao.findAll();
	}

	@Override
	public Major findMajorById(int id) {
		return majorDao.findById(id);
	}

	
	@Override
	public Major findMajorByMajorId(String majorId) {
		return majorDao.findMajorByMajorId(majorId);
	}

	@Override
	public void saveMajor(Major major) {
		majorDao.save(major);
	}

	@Override
	public void updateMajor(Major major) {
		majorDao.update(major);
	}

	@Override
	public void deleteClazzById(int id) {
		Clazz clazz = clazzDao.findById(id);
		clazzDao.delete(clazz);
	}

	@Override
	public Clazz findClazzById(int id) {
		return clazzDao.findById(id);
	}

	@Override
	public List<Clazz> findClazzs() {
		return clazzDao.findAll();
	}

	@Override
	public Integer saveClazz(Clazz clazz) {
		return clazzDao.save(clazz);
	}

	@Override
	public void updateClazz(Clazz clazz) {
		clazzDao.update(clazz);
	}

	@Override
	public void deleteCourseById(int id) {
		Course course = courseDao.findById(id);
		courseDao.delete(course);
	}

	@Override
	public Course findCourseById(int id) {
		return courseDao.findById(id);
	}

	@Override
	public List<Course> findCourses() {
		return courseDao.findAll();
	}

	@Override
	public void saveCourse(Course course) {
		courseDao.save(course);
	}

	@Override
	public void updateCourse(Course course) {
		courseDao.update(course);
	}

	@Override
	public void deleteTermById(int id) {
		Term term = termDao.findById(id);
		termDao.delete(term);

	}

	@Override
	public Term findTermById(int id) {
		return termDao.findById(id);
	}

	@Override
	public List<Term> findTerms() {
		return termDao.findAll();
	}

	@Override
	public void saveTerm(Term term) {
		termDao.save(term);
	}

	@Override
	public void updateTerm(Term term) {
		termDao.update(term);
	}

	@Override
	public void deleteTeacherById(int id) {

		User teacher = userDao.findById(id);
		userDao.delete(teacher);

	}

	@Override
	public Teacher findTeacherById(int id) {
		return teacherDao.findById(id);
	}
	
	@Override
	public Teacher findTeacherByTeachId(String teachId) {
		return teacherDao.findTeacherByTeachId(teachId);
	}
	
	@Override
	public Teacher findTeacherByUserId(int id) {
		return teacherDao.findById(id);
	}
	
	@Override
	public List<Teacher> findTeachers() {
		return teacherDao.findAll();
	}

	@Override
	public void saveTeacher(Teacher teacher) {
		teacherDao.save(teacher);
	}

	@Override
	public void updateTeacher(Teacher teacher) {
		teacherDao.update(teacher);
	}

	@Override
	public void deleteStudentById(int id) {
		User student = userDao.findById(id);
		userDao.delete(student);
	}

	@Override
	public Student findStudentById(int id) {
		return studentDao.findById(id);
	}

	@Override
	public List<Student> findStudents() {
		return studentDao.findAll();
	}

	@Override
	public void saveStudent(Student student) {
		studentDao.save(student);
	}

	@Override
	public void updateStudent(Student student) {
		studentDao.update(student);
	}

	public Student findStudentByStuId(String id){
		return studentDao.findStudentByStuId(id);
	}
	
	@Override
	public List<Major> findMajorsOfDept(Department dept) {
		return majorDao.findMajorsOfDept(dept.getId());
	}

	@Override
	public List<Clazz> findClazzsOfMajor(Major major) {
		return clazzDao.findClazzsOfMajor(major.getId());
	}

	@Override
	public Role findRoleByName(String name) {
		return roleDao.findRoleByName(name);
	}

	@Override
	public Clazz findClazzByClazzId(String clazzId) {
		return clazzDao.findClazzByClazzId(clazzId);
	}

	@Override
	public List<Teacher> findTeachersOfDept(Department dept) {
		return teacherDao.findTeacherOfDept(dept.getId());
	}

	@Override
	public List<Course> findCoursesOfMajor(Major major) {
		return courseDao.findCoursesOfMajor(major.getId());
	}

	@Override
	public Term findTermOfNow() {
		return termDao.findTermOfNow();
	}

	@Override
	public Term findTermByTimeAndOrder(int startYear, int endYear, int order) {
		return termDao.findTermByTimeAndOrder(startYear, endYear, order);
	}

	@Override
	public List<Course> findCoursesOfType(int id) {
		return courseDao.findCoursesOfType(id);
	}
		
	@Override
	public Course findCourseByCourseId(String courseId){
		return courseDao.findCourseByCourseId(courseId);
	}
}
